package com.java.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONArray;
import com.java.entity.ExChapter;
import com.java.entity.ExChapterItem;
import com.java.entity.ExTopic;
import com.java.entity.ExTopicOption;
import com.java.entity.ExTopicResp;
import com.java.entity.vo.ExTopicVo;
import com.java.entity.vo.WrongInfo;
import com.java.mapper.ExAccountMapper;
import com.java.mapper.ExChapterItemMapper;
import com.java.mapper.ExChapterMapper;
import com.java.mapper.ExChapterRecordMapper;
import com.java.mapper.ExTopicMapper;
import com.java.mapper.ExTopicOptionMapper;
import com.java.mapper.ExTopicRespMapper;
import com.java.service.TopicService;
import com.java.util.MyMap;
import com.java.util.MyTools;
import com.java.util.resp.BaseRespone;
import com.java.util.resp.TableRespone;

@Service
public class TopicServiceImpl implements TopicService {
	
	@Autowired private ExAccountMapper accountMapper;
	@Autowired private ExChapterMapper chapterMapper;
	@Autowired private ExChapterItemMapper chapterItemMapper;
	@Autowired private ExChapterRecordMapper chapterRecordMapper;
	@Autowired private ExTopicMapper topicMapper;
	@Autowired private ExTopicOptionMapper topicOptionMapper;
	@Autowired private ExTopicRespMapper topicRespMapper;

	@Override
	public BaseRespone saveTopic(String chapterId, ExTopicVo topic) {
		int row = 0;
		ExTopic select = topicMapper.selectByKey(topic.getTopicId());
		if(null == select) {
			select = new ExTopic()
			.setTopicId(MyTools.getUUID())
			.setTopicDelete(0)
			.setTopicTime(new Date())
			.setTopicChapterId(chapterId)
			
			.setTopicTitle(topic.getTopicTitle())
			.setTopicType(topic.getTopicType())
			.setTopicContent(topic.getTopicContent())
			.setTopicLevel(topic.getTopicLevel())
			.setTopicAnswer(topic.getTopicAnswer())
			.setTopicAnalysis(topic.getTopicAnalysis());
			// 0单选题，1多选题，3填空题
			if(topic.getTopicType() == 0 || topic.getTopicType() == 1) {
				List<ExTopicOption> oplist = topic.getOptions();
				for (ExTopicOption option : oplist) {
					option.setOptionId(MyTools.getUUID());
					option.setOptionTopicId(select.getTopicId());
					option.setOptionDelete(0);
					option.setOptionSort(1);
					if(topic.getTopicType() == 0) {
						if(option.getOptionAnswer() == 1) {
							select.setTopicAnswer(option.getOptionId());
						}
					}
				}
				topicOptionMapper.insertBatch(oplist);
			}
			row = topicMapper.insertSelective(select);
			if(row > 0) {
				ExChapterItem item = new ExChapterItem()
						.setItemId(MyTools.getUUID())
						.setItemChapterId(chapterId)
						.setItemTopicId(select.getTopicId())
						.setItemDelete(0)
						.setItemTime(new Date());
				chapterItemMapper.insertSelective(item);
				// 刷新总数
				updateCount(chapterId);
			}
		}else {
			topicOptionMapper.deleteUpdateByTopic(select.getTopicId());
			if(select.getTopicType() == 0 || select.getTopicType() == 1) {
				List<ExTopicOption> oplist = topic.getOptions();
				for (ExTopicOption option : oplist) {
					option.setOptionId(MyTools.getUUID());
					option.setOptionTopicId(topic.getTopicId());
					option.setOptionDelete(0);
					option.setOptionSort(1);
					if(topic.getTopicType() == 0) {
						if(option.getOptionAnswer() == 1) {
							select.setTopicAnswer(option.getOptionId());
						}
					}
				}
				topicOptionMapper.insertBatch(oplist);
			}
			select.setTopicTitle(topic.getTopicTitle())
			.setTopicContent(topic.getTopicContent())
			.setTopicLevel(topic.getTopicLevel())
			.setTopicAnswer(topic.getTopicAnswer())
			.setTopicAnalysis(topic.getTopicAnalysis());
			row = topicMapper.updateSelective(select);
		}
		return BaseRespone.result(row, "保存成功");
	}

	@Override
	public BaseRespone updateTopic(ExTopic topic) {
		return null;
	}
	public void updateCount(String chapterId) {
		try {
			long selectAllCount = topicMapper.selectVoByChapterCount(chapterId);
			ExChapter ch = new ExChapter();
			ch.setChapterId(chapterId);
			ch.setChapterCount((int)selectAllCount);
			chapterMapper.updateSelective(ch);
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
	}

	/*@Override
	public TableRespone getTopics(String chapterId, int page, int pageSize) {
		int offset = TableRespone.getOffset(page, pageSize);
		List<ExTopicVo> selectAll = topicMapper.selectVoByChapter(chapterId, offset, pageSize);
		long selectAllCount = topicMapper.selectVoByChapterCount(chapterId);
		return new TableRespone(selectAll, selectAllCount);
	}*/
	
	@Override
	public List<ExTopic> getAllTopic() {
		MyMap mm = new MyMap().put("topicDelete", "0");
		List<ExTopic> tlist = topicMapper.selectAll(mm, 0, 0);
		return tlist;
	}

	@Override
	public TableRespone getChapterTopicVos(String chapterId, int page, int pageSize) {
		int offset = TableRespone.getOffset(page, pageSize);
		List<ExTopicVo> selectAll = topicMapper.selectVoByChapter(chapterId, offset, pageSize);
		long selectAllCount = topicMapper.selectVoByChapterCount(chapterId);
		for (ExTopicVo exTopicVo : selectAll) {
			if(exTopicVo.getTopicType() == 1 && null != exTopicVo.getOptions()) {
				List<String> ops = new ArrayList<String>();
				for (ExTopicOption option : exTopicVo.getOptions()) {
					if(option.getOptionAnswer() == 1) {
						ops.add(option.getOptionId());
					}
				}
				exTopicVo.setTopicAnswers(ops);
			}
		}
		return new TableRespone(selectAll, selectAllCount);
	}

	@Override
	public TableRespone getExamTopicVos(String chapterId, String accountId, int page, int pageSize) {
		ExChapter chapter = chapterMapper.selectByKey(chapterId);
		int offset = TableRespone.getOffset(page, pageSize);
		List<ExTopicVo> selectAll = new ArrayList<ExTopicVo>();
		long selectAllCount = 0;
		if(chapter.getChapterType() == 0) {
			selectAll = topicMapper.selectVoChapterByExam(accountId, chapterId, offset, pageSize);
			selectAllCount = topicMapper.selectVoChapterCountByExam(accountId, chapterId);
		}else {
			selectAll = topicMapper.selectVoByExam(accountId, chapterId, offset, pageSize);
			selectAllCount = topicMapper.selectVoByExamCount(accountId, chapterId);
		}
		for (ExTopicVo exTopicVo : selectAll) {
			if(exTopicVo.getTopicType() == 1 && null != exTopicVo.getOptions()) {
				List<String> ops = new ArrayList<String>();
				for (ExTopicOption option : exTopicVo.getOptions()) {
					if(option.getOptionAnswer() == 1) {
						ops.add(option.getOptionId());
					}
				}
				exTopicVo.setTopicAnswers(ops);
			}
			/*ExTopicResp resp = topicRespMapper.selectByInfo(
					new ExTopicResp().setRespRecordId(exTopicVo.getRecordId()).setRespAccountId(accountId).setRespItemId(exTopicVo.getTopicId()));
			exTopicVo.setResp(resp);*/
		}
		return new TableRespone(selectAll, selectAllCount);
	}

	@Override
	public ExTopicVo getTopicVo(String topicId) {
		return topicMapper.selectVo(topicId);
	}

	@Override
	public ExTopic getTopic(String topicId) {
		return topicMapper.selectByKey(topicId);
	}

	@Override
	public BaseRespone deleteTopic(String chapterId, String topicId) {
		//ExTopic tp = topicMapper.selectByKey(topicId);
		// 刷新总数
		topicMapper.deleteUpdate(topicId, "topic_delete");
		updateCount(chapterId);
		return BaseRespone.success("已删除");
	}

	@Override
	public List<ExTopicOption> getTopicOptions(String topicId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone updateTopicOption(ExTopicOption option) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone deleteTopicOption(String optionId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone saveTopicResp(ExTopicResp resp) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone getTopicResps(String chapterId, String accountId, int page, int pageSize) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone getTopicResp(String respId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone getTopicResp(String chapterId, String accountId, String itemId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseRespone loadTopic(String chapterExamId, Integer count) {
		if(null == count) {
			count = 100;
		}
		List<ExChapterItem> itemList = new ArrayList<ExChapterItem>();
		List<ExTopic> notList = new ArrayList<ExTopic>();
		int selectCount = 0;
		try {
			List<ExChapter> allChapter = chapterMapper
					.selectAll(new MyMap().put("chapterType", 0).put("chapterDelete", 0), 0, 0);
			if(MyTools.isEmpty(allChapter)) {
				return new BaseRespone(0, "未添加章节");
			}
			for (ExChapter chapter : allChapter) {
				// 遍历获取章节设置的题目列表
				List<ExTopic> ctlist = topicMapper.selectAll(
						new MyMap().put("topicDelete", "0").put("topicChapterId", chapter.getChapterId()), 0, 0);
				if(!MyTools.isEmpty(ctlist)) {
					// 题目总长度
					int tsize = ctlist.size();
					// 所需的权重转数量，取整数型的值
					int needCount = chapter.getChapterWeight().multiply(new BigDecimal(tsize))
							.divide(new BigDecimal(100), 0, BigDecimal.ROUND_HALF_DOWN).intValue();
					// 如果权重整数型等于0，那就跳出循环
					if(needCount == 0) {
						// 因为是取整，所以可能1条的情况下，取不出来，那就记录到补差里面，然后跳出计算
						if(ctlist.size() > 0) {
							notList.addAll(ctlist);
						}
						continue;
					}
					// 判断所需的数量跟章节实际题目数量
					if(tsize < needCount) {
						// 如果题目总数小于权重所需，那就赋值取最小值
						needCount = tsize;
					}
					// 记录已选择的题目数量
					selectCount = selectCount + needCount;
					// 获取随机数数组
					List<Integer> tlist = MyTools.randomNumbers(0, tsize - 1, needCount);
					for (Integer integer : tlist) {
						// 根据随机序号获取题目的ID记录起来
						ExTopic topic = ctlist.get(integer);
						ExChapterItem item = new ExChapterItem()
								.setItemId(MyTools.getUUID())
								.setItemChapterId(chapterExamId)
								.setItemTopicId(topic.getTopicId())
								.setItemDelete(0)
								.setItemTime(new Date());
						itemList.add(item);
					}
					// 记录没有被随机到的题目，等会可能用来做补差计算
					List<ExTopic> syList =  excludeIndexes(ctlist, tlist);
					if(syList.size() > 0) {
						notList.addAll(syList);
					}
				}
			}
			// 最后判断选择的数量是否达到总权重（其实就是100）条数，
			// 如果达不到100条则判断实际上所有题目是否超过选择的数量
			if(selectCount < count) {
				// 如果不超过则结束，如果超过了选择的数量，那就补差值→总题目数量-selectCount=补差的条数
				int diff = count - selectCount;
				// 如果得到差值之后，实际上还没被抽取的总题目根本没有这么多
				// List<ExTopic> tlist = topicMapper.selectAll(new MyMap().put("topicDelete", "0"), 0, 0);
				// 所以还没被抽取的总条数要大于想要的条数再去补差值，否则的话就继续重新计算取补差值
				if(diff > notList.size()) {
					diff = notList.size();
				}
				// 随机获取剩余未被抽取的序号
				List<Integer> list = MyTools.randomNumbers(0, notList.size() - 1, diff);
				for (Integer dif : list) {
					ExChapterItem item = new ExChapterItem()
							.setItemId(MyTools.getUUID())
							.setItemChapterId(chapterExamId)
							.setItemTopicId(notList.get(dif).getTopicId())
							.setItemDelete(0)
							.setItemTime(new Date());
					itemList.add(item);
				}
			}
		} catch (Exception e) {
			return new BaseRespone(0, "计算题目异常");
		}
		if(itemList.size() > 0) {
			// 最后进行批量操作
			chapterItemMapper.updateDeleteByChapter(chapterExamId);
			chapterItemMapper.insertBatch(itemList);
			return new BaseRespone(selectCount, "生成成功");
		}
		return new BaseRespone(0, "计算题目为空");
	}
	
	public List<ExTopic> excludeIndexes(List<ExTopic> topics, List<Integer> indexs) {
		List<ExTopic> topicsBak = new ArrayList<ExTopic>();
		if(MyTools.isEmpty(topics) || topics.size() == 0) {
			return topicsBak;
		}
		if(MyTools.isEmpty(indexs) || indexs.size() == 0) {
			return topicsBak;
		}
		// 深度拷贝、避免影响原数组
		for (ExTopic exTopic : topics) {
			topicsBak.add(exTopic);
		}
        // 对B中的索引进行降序排序，这样从后向前删除元素时不会影响前面的索引  
		indexs.sort(null); // 使用null作为比较器，进行自然排序（升序），之后反转列表  
        Collections.reverse(indexs);  
        // 遍历B中的索引，并从A中删除相应的元素  
        for (int index : indexs) {  
            if (index >= 0 && index < topicsBak.size()) {  
            	topicsBak.remove(index);  
            }  
        }
		return topicsBak;  
    }

	@Override
	public TableRespone getWrongs(String accountId, String recordId, Integer result, int page, int pageSize) {
		int offset = TableRespone.getOffset(page, pageSize);
		List<WrongInfo> list = topicMapper.selectWrongs(accountId, recordId, result, offset, pageSize);
		long count = topicMapper.selectWrongCount(accountId, recordId, result);
		for (WrongInfo info : list) {
			if(info.getTopicType() == 0) {
				List<String> alist = new ArrayList<String>();
				alist.add(info.getRespAnswer());
				info.setRespAnswers(alist);
			}
			if(info.getTopicType() == 1) {
				List<String> alist = JSONArray.parseArray(info.getRespAnswer(), String.class);
				info.setRespAnswers(alist);
			}
			List<String> tlist = new ArrayList<String>();
			for (ExTopicOption op : info.getOptions()) {
				if(op.getOptionAnswer() == 1) {
					tlist.add(op.getOptionText());
				}
			}
			info.setTopicAnswers(tlist);
		}
		return new TableRespone(list, count);
	}

	@Override
	public BaseRespone delAllTopic(List<String> list) {
		for (String tId : list) {
			topicMapper.deleteUpdate(tId, "topic_delete");
		}
		return BaseRespone.success("已删除");
	}

}
